crash> dis int3
0xffffffff817000f0 <int3>:      nopw   0x0(%rax,%rax,1)
0xffffffff817000f6 <int3+6>:    pushq  $0xffffffffffffffff
0xffffffff817000f8 <int3+8>:    sub    $0x78,%rsp
0xffffffff817000fc <int3+12>:   callq  0xffffffff81700040 <save_paranoid>
0xffffffff81700101 <int3+17>:   mov    %rsp,%rdi
0xffffffff81700104 <int3+20>:   xor    %esi,%esi
0xffffffff81700106 <int3+22>:   mov    %gs:0xe0b0,%rbp
0xffffffff8170010f <int3+31>:   lea    0x14280(%rbp),%rbp
0xffffffff81700116 <int3+38>:   subq   $0x1000,0x3c(%rbp)
0xffffffff8170011e <int3+46>:   callq  0xffffffff81700820 <do_int3>
0xffffffff81700123 <int3+51>:   addq   $0x1000,0x3c(%rbp)
0xffffffff8170012b <int3+59>:   jmpq   0xffffffff81700260 <paranoid_exit>


.macro paranoidzeroentry_ist sym do_sym ist
ENTRY(\sym)
	INTR_FRAME
	PARAVIRT_ADJUST_EXCEPTION_FRAME
	pushq $-1		/* ORIG_RAX: no syscall to restart */
	CFI_ADJUST_CFA_OFFSET 8
	subq $15*8, %rsp
	call save_paranoid
	TRACE_IRQS_OFF
	movq %rsp,%rdi		/* pt_regs pointer */
	xorl %esi,%esi		/* no error code */
	PER_CPU(init_tss, %rbp)
	subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
	call \do_sym
	addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
	jmp paranoid_exit	/* %ebx: no swapgs flag */
	CFI_ENDPROC
END(\sym)
.endm

/*

crash> struct -xo pt_regs
struct pt_regs {
   [0x0] unsigned long r15;
   [0x8] unsigned long r14;
  [0x10] unsigned long r13;
  [0x18] unsigned long r12;
  [0x20] unsigned long bp;
  [0x28] unsigned long bx;
  [0x30] unsigned long r11;
  [0x38] unsigned long r10;
  [0x40] unsigned long r9;
  [0x48] unsigned long r8;
  [0x50] unsigned long ax;
  [0x58] unsigned long cx;
  [0x60] unsigned long dx;
  [0x68] unsigned long si;
  [0x70] unsigned long di;
  [0x78] unsigned long orig_ax;  偏移0x80
/* 硬件自动压栈 */
  [0x80] unsigned long ip;
  [0x88] unsigned long cs;
  [0x90] unsigned long flags;
  [0x98] unsigned long sp;
  [0xa0] unsigned long ss;
}

 */



/* 调用save_paranoid的时候用call指令，所以rsp会减8，用来保持返回地址
 * 所以保持reg的栈是从rsp-8开始的
 */
0xffffffff81700040 <save_paranoid>:     cld    
0xffffffff81700041 <save_paranoid+1>:   mov    %rdi,0x78(%rsp)
0xffffffff81700046 <save_paranoid+6>:   mov    %rsi,0x70(%rsp)
0xffffffff8170004b <save_paranoid+11>:  mov    %rdx,0x68(%rsp)
0xffffffff81700050 <save_paranoid+16>:  mov    %rcx,0x60(%rsp)
0xffffffff81700055 <save_paranoid+21>:  mov    %rax,0x58(%rsp)
0xffffffff8170005a <save_paranoid+26>:  mov    %r8,0x50(%rsp)
0xffffffff8170005f <save_paranoid+31>:  mov    %r9,0x48(%rsp)
0xffffffff81700064 <save_paranoid+36>:  mov    %r10,0x40(%rsp)
0xffffffff81700069 <save_paranoid+41>:  mov    %r11,0x38(%rsp)
0xffffffff8170006e <save_paranoid+46>:  mov    %rbx,0x30(%rsp)
0xffffffff81700073 <save_paranoid+51>:  mov    %rbp,0x28(%rsp)
0xffffffff81700078 <save_paranoid+56>:  mov    %r12,0x20(%rsp)
0xffffffff8170007d <save_paranoid+61>:  mov    %r13,0x18(%rsp)
0xffffffff81700082 <save_paranoid+66>:  mov    %r14,0x10(%rsp)
0xffffffff81700087 <save_paranoid+71>:  mov    %r15,0x8(%rsp)
0xffffffff8170008c <save_paranoid+76>:  mov    $0x1,%ebx
0xffffffff81700091 <save_paranoid+81>:  mov    $0xc0000101,%ecx
0xffffffff81700096 <save_paranoid+86>:  rdmsr  
0xffffffff81700098 <save_paranoid+88>:  test   %edx,%edx
0xffffffff8170009a <save_paranoid+90>:  js     0xffffffff817000a4 <save_paranoid+100>
0xffffffff8170009c <save_paranoid+92>:  swapgs 
0xffffffff8170009f <save_paranoid+95>:  nopl   (%rax)
0xffffffff817000a2 <save_paranoid+98>:  xor    %ebx,%ebx
0xffffffff817000a4 <save_paranoid+100>: retq


/* save complete stack frame */
	.pushsection .kprobes.text, "ax"
ENTRY(save_paranoid)
	XCPT_FRAME 1 RDI+8
	cld
	movq_cfi rdi, RDI+8
	movq_cfi rsi, RSI+8
	movq_cfi rdx, RDX+8
	movq_cfi rcx, RCX+8
	movq_cfi rax, RAX+8
	movq_cfi r8, R8+8
	movq_cfi r9, R9+8
	movq_cfi r10, R10+8
	movq_cfi r11, R11+8
	movq_cfi rbx, RBX+8
	movq_cfi rbp, RBP+8
	movq_cfi r12, R12+8
	movq_cfi r13, R13+8
	movq_cfi r14, R14+8
	movq_cfi r15, R15+8
	movl $1,%ebx
	movl $MSR_GS_BASE,%ecx
	rdmsr
	testl %edx,%edx  /* edx应该是小于0的 */
	js 1f	/* negative -> in kernel */
	SWAPGS
	xorl %ebx,%ebx
1:	ret
	CFI_ENDPROC
END(save_paranoid)
	.popsection


ENTRY(paranoid_exit)
	INTR_FRAME
	DISABLE_INTERRUPTS(CLBR_NONE)
	TRACE_IRQS_OFF
	/* ebx为1 */
	testl %ebx,%ebx				/* swapgs needed? */
	jnz paranoid_restore
	testl $3,CS(%rsp)
	jnz   paranoid_userspace
paranoid_swapgs:
	TRACE_IRQS_IRETQ 0
	SWAPGS_UNSAFE_STACK
	RESTORE_ALL 8
	jmp irq_return
paranoid_restore:
	TRACE_IRQS_IRETQ 0
	RESTORE_ALL 8
	jmp irq_return
paranoid_userspace:
	GET_THREAD_INFO(%rcx)
	movl TI_flags(%rcx),%ebx
	andl $_TIF_WORK_MASK,%ebx
	jz paranoid_swapgs
	movq %rsp,%rdi			/* &pt_regs */
	call sync_regs
	movq %rax,%rsp			/* switch stack for scheduling */
	testl $_TIF_NEED_RESCHED,%ebx
	jnz paranoid_schedule
	movl %ebx,%edx			/* arg3: thread flags */
	TRACE_IRQS_ON
	ENABLE_INTERRUPTS(CLBR_NONE)
	xorl %esi,%esi 			/* arg2: oldset */
	movq %rsp,%rdi 			/* arg1: &pt_regs */
	call do_notify_resume
	DISABLE_INTERRUPTS(CLBR_NONE)
	TRACE_IRQS_OFF
	jmp paranoid_userspace
paranoid_schedule:
	TRACE_IRQS_ON
	ENABLE_INTERRUPTS(CLBR_ANY)
	call schedule
	DISABLE_INTERRUPTS(CLBR_ANY)
	TRACE_IRQS_OFF
	jmp paranoid_userspace
	CFI_ENDPROC
END(paranoid_exit)


crash> dis paranoid_restore
/* 因为调用save_paranoid时rsp减了8，所以调用paranoid_restore时，rsp比调用 save_paranoid时少了rsp的偏移少了8 */
0xffffffff817002d6 <paranoid_restore>:  		mov    (%rsp),%r15
0xffffffff817002da <paranoid_restore+4>:        mov    0x8(%rsp),%r14
0xffffffff817002df <paranoid_restore+9>:        mov    0x10(%rsp),%r13
0xffffffff817002e4 <paranoid_restore+14>:       mov    0x18(%rsp),%r12
0xffffffff817002e9 <paranoid_restore+19>:       mov    0x20(%rsp),%rbp
0xffffffff817002ee <paranoid_restore+24>:       mov    0x28(%rsp),%rbx
0xffffffff817002f3 <paranoid_restore+29>:       add    $0x30,%rsp
0xffffffff817002f7 <paranoid_restore+33>:       mov    (%rsp),%r11
0xffffffff817002fb <paranoid_restore+37>:       mov    0x8(%rsp),%r10
0xffffffff81700300 <paranoid_restore+42>:       mov    0x10(%rsp),%r9
0xffffffff81700305 <paranoid_restore+47>:       mov    0x18(%rsp),%r8
0xffffffff8170030a <paranoid_restore+52>:       mov    0x20(%rsp),%rax
0xffffffff8170030f <paranoid_restore+57>:       mov    0x28(%rsp),%rcx
0xffffffff81700314 <paranoid_restore+62>:       mov    0x30(%rsp),%rdx
0xffffffff81700319 <paranoid_restore+67>:       mov    0x38(%rsp),%rsi
0xffffffff8170031e <paranoid_restore+72>:       mov    0x40(%rsp),%rdi
0xffffffff81700323 <paranoid_restore+77>:       add    $0x50,%rsp
0xffffffff81700327 <paranoid_restore+81>:       jmpq   0xffffffff8100ba4e <irq_return>
